package com.sc.study.student.service.impl;

import java.io.IOException;
import java.util.*;

import com.alibaba.fastjson.JSON;
import com.sc.common.core.redis.RedisCache;
import com.sc.common.utils.DateUtils;
import com.sc.study.clazz.domain.ScClazz;
import com.sc.study.clazz.domain.ScClazzSubject;
import com.sc.study.clazz.mapper.ScClazzMapper;
import com.sc.study.clazz.mapper.ScClazzSubjectMapper;
import com.sc.study.foundation.domain.ScSubject;
import com.sc.study.foundation.mapper.ScSubjectMapper;
import com.sc.study.sleeproom.domain.ScSleepRoom;
import com.sc.study.sleeproom.service.IScSleepRoomPersonService;
import com.sc.study.student.domain.ScStudentClazz;
import com.sc.study.student.domain.ScStudentSubject;
import com.sc.study.student.mapper.ScStudentClazzMapper;
import com.sc.study.student.mapper.ScStudentSubjectMapper;
import com.sc.system.service.ISysConfigService;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sc.study.student.mapper.ScStudentMapper;
import com.sc.study.student.domain.ScStudent;
import com.sc.study.student.service.IScStudentService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 * 学员Service业务层处理
 *
 * @author sc
 * @date 2022-02-27
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ScStudentServiceImpl implements IScStudentService {
    @Autowired
    private ScStudentMapper scStudentMapper;

    @Autowired
    private ScClazzMapper scClazzMapper;

    @Autowired
    private ScStudentClazzMapper scStudentClazzMapper;

    @Autowired
    private ScStudentSubjectMapper scStudentSubjectMapper;

    @Autowired
    private ScClazzSubjectMapper scClazzSubjectMapper;

    @Autowired
    private ScSubjectMapper scSubjectMapper;


    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private IScSleepRoomPersonService scSleepRoomPersonService;


    @Override
    public List<ScStudent> selectScStudentNoClazz(ScStudent scStudent) {
        return scStudentMapper.selectScStudentNoClazz(scStudent);
    }


    /**
     * 根据学生的code查询
     * @param stuCode
     * @return
     */
    @Override
    public ScStudent getByCode(Long stuCode) {
        ScStudent byCode = scStudentMapper.getByCode(stuCode);

        if(byCode == null) throw new RuntimeException("未查找到" + stuCode + "的学生数据");


        //获取学上的寝室人员类型数组值
        List<Long> sleep_room_person_type_stu = JSON.parseArray(sysConfigService.selectConfigByKey("sleep_room_person_type_stu"), Long.class);

        Integer bindPersonIdSize = scSleepRoomPersonService.getBindPersonIdSize(byCode.getId(), sleep_room_person_type_stu);

        if(bindPersonIdSize > 0) throw new RuntimeException("该学生已经分配寝室");

        return byCode;
    }

    /**
     * 根据学生编号查询
     * @param id
     * @return
     */
    @Override
    public ScStudent getOne(Long id) {
        return scStudentMapper.selectScStudentById(id);
    }

    /**
     * 查询学员
     *
     * @param id 学员主键
     * @return 学员
     */
    @Override
    public ScStudent selectScStudentById(Long id) {
        Integer studentCode = Integer.parseInt(sysConfigService.selectConfigByKey("student_code"));

        ScStudent scStudent = scStudentMapper.selectScStudentById(id);
        ScStudentClazz scStudentClazz = new ScStudentClazz();
        scStudentClazz.setClazzpersontypeid(studentCode);
        // 如果学员班级不是空的就带出班级
        if (scStudent.getStudentclazzid() != null) {
            scStudentClazz.setId(scStudent.getStudentclazzid());
            ScStudentClazz studentClazz = scStudentClazzMapper.selectScStudentClazzList(scStudentClazz).get(0);
            ScClazz scClazz = scClazzMapper.selectScClazzById(studentClazz.getClazzid());
            scStudent.setStudentclazzid(scClazz.getId());
        }
        return scStudent;
    }

    /**
     * 查询学员列表
     *
     * @param scStudent 学员
     * @return 学员
     */
    @Override
    public List<ScStudent> selectScStudentList(ScStudent scStudent) {

        return scStudentMapper.selectScStudentList(scStudent);
    }

    /**
     * 查询学员列表包含班级
     *
     * @param scStudent 学员
     * @return 学员
     */
    @Override
    public List<ScStudent> selectScStudentIncludeClazz(ScStudent scStudent) {
        return scStudentMapper.selectScStudentIncludeClazz(scStudent);
    }

    /**
     * 查询学生
     *
     * @param scStudent
     * @return
     */
    @Override
    public List<ScStudent> find(ScStudent scStudent) {
        return scStudentMapper.selectScStudentList(scStudent);
    }

    /**
     * 新增学员
     *
     * @param scStudent 学员
     * @return 结果
     */
    @Override
    public int insertScStudent(ScStudent scStudent) {
        //Studentclazzid : 前台传入的是班级id
        ScClazz scClazz = scClazzMapper.selectScClazzById(scStudent.getStudentclazzid());
        int studentCode = Integer.parseInt(sysConfigService.selectConfigByKey("student_code"));

        //添加学生
        int i = scStudentMapper.insertScStudent(scStudent);
        //未传入班级编号，表示学生未进行分班
        if (i > 0 && scStudent.getStudentclazzid() != null) {
            //完成学生的添加才能拿到学生的编号
            ScStudentClazz scStudentClazz = new ScStudentClazz(scStudent.getStudentclazzid(), scStudent.getId(), scClazz.getGradeid(), studentCode, DateUtils.getLocalDateTime());
            //增加学生与班级的关联
            int i1 = scStudentClazzMapper.insertScStudentClazz(scStudentClazz);
            //将学生的班级编号修改成学生对应的（学员班级编号）
            scStudent.setStudentclazzid(scStudentClazz.getId());
            scStudentMapper.updateScStudent(scStudent);


            // 查询班级有哪些科目
            ScClazzSubject scClazzSubject = new ScClazzSubject();
            scClazzSubject.setClazzid(scClazz.getId());
            List<ScClazzSubject> scClazzSubjectList = scClazzSubjectMapper.selectScClazzSubjectList(scClazzSubject);

            if (scClazzSubjectList.size() > 0) {
                // 添加学员课程
                scClazzSubjectList.forEach(item -> {
                    ScSubject scSubject = scSubjectMapper.selectScSubjectBySubid(item.getSubid());
                    ScStudentSubject scStudentSubject = new ScStudentSubject(scSubject.getSubid(), scStudent.getId(), scSubject.getSubtime(), 0L);
                    scStudentSubjectMapper.insertScStudentSubject(scStudentSubject);

                });
            }


        }
        return i;
    }


    /**
     * 修改学员
     *
     * @param scStudent 学员
     * @return 结果
     */
    @Override
    public int updateScStudent(ScStudent scStudent) {
        int studentCode = Integer.parseInt(sysConfigService.selectConfigByKey("student_code"));
        // studentclazzid 为班级编号

        // 如果传过来的班级编号为空 就将当前学员对应的学员班级表数据out_time设置为当前时间 并将studentclazzid设置为空
        ScStudent student = scStudentMapper.selectScStudentById(scStudent.getId());
        ScStudentClazz scStudentClazz = scStudentClazzMapper.selectScStudentClazzById(student.getStudentclazzid());
        if (scStudent.getStudentclazzid() == null) {
            // 先查到之前的学员数据
            // 根据student找到学员班级表数据设置out_time
            scStudentClazz.setOuttime(DateUtils.getLocalDateTime());
            scStudentClazzMapper.updateScStudentClazz(scStudentClazz);

            // 修改学员状态为空
            scStudentMapper.updateScStudentStudentClazzId(student);

        }
        // 如果传过来的班级编号不为空，就将当前学员对应的学员班级表数据out_time设置为当前时间，并新增一个对应的学员班级表
        else {
            // 先查到之前的学员数据
            // 根据student找到学员班级表数据设置out_time
            if (scStudentClazz != null) {
                scStudentClazz.setOuttime(DateUtils.getLocalDateTime());
                scStudentClazzMapper.updateScStudentClazz(scStudentClazz);
            }

            // 新增一个
            ScClazz scClazz = scClazzMapper.selectScClazzById(scStudent.getStudentclazzid());

            ScStudentClazz newScStudentClazz = new ScStudentClazz(scClazz.getId(), student.getId(), scClazz.getGradeid(), studentCode, DateUtils.getLocalDateTime());
            scStudentClazzMapper.insertScStudentClazz(newScStudentClazz);

            // 修改学员班级编号
            student.setStudentclazzid(newScStudentClazz.getId());
            scStudentMapper.updateScStudent(student);

        }

        return 1;

    }

    /**
     * 批量删除学员
     *
     * @param ids 需要删除的学员主键
     * @return 结果
     */
    @Override
    public int deleteScStudentByIds(Long[] ids) {
        return scStudentMapper.deleteScStudentByIds(ids);
    }

    /**
     * 删除学员信息
     *
     * @param id 学员主键
     * @return 结果
     */
    @Override
    public int deleteScStudentById(Long id) {
        return scStudentMapper.deleteScStudentById(id);
    }

    /**
     * 移除学员信息
     *
     * @param scStudent 学员
     * @return 结果
     */
    @Override
    public int removeStudent(ScStudent scStudent) {
        // 将学员的学员班级编号修改为空
        scStudentMapper.updateScStudentStudentClazzId(scStudent);
        // 将学员班级表中的学员数据设为离开
        ScStudentClazz scStudentClazz = new ScStudentClazz();
        scStudentClazz.setStudentid(scStudent.getId());

        scStudentClazz.setClazzpersontypeid(Integer.parseInt(sysConfigService.selectConfigByKey("student_code")));
        ScStudentClazz scStudentClazz1 = scStudentClazzMapper.selectScStudentClazzList(scStudentClazz).get(0);
        // 将学员班级中的离开时间设置为当前时间
        scStudentClazz1.setOuttime(DateUtils.getLocalDateTime());

        ScStudentSubject scStudentSubject = new ScStudentSubject();
        scStudentSubject.setStudentid(scStudent.getId());
        // 删除学员对应的科目
        List<ScStudentSubject> scStudentSubjectList = scStudentSubjectMapper.selectScStudentSubjectList(scStudentSubject);
        scStudentSubjectList.forEach(item -> {
            scStudentSubjectMapper.deleteScStudentSubjectById(item.getId());
        });

        return scStudentClazzMapper.updateScStudentClazz(scStudentClazz1);
    }

    /**
     * 导入Excel
     *
     * @param file    Excel
     * @param clazzId 班级编号
     * @throws IOException
     */
    @Override
    public void importExcel(MultipartFile file, Long clazzId) throws IOException {
        //将传入进来的文件转化为工作簿
        Workbook workbook = new XSSFWorkbook(file.getInputStream());
        //获取excel sheet页面
        Sheet sheet = workbook.getSheetAt(0);
        //获取当前sheet页行数
        int rows = sheet.getPhysicalNumberOfRows();

        for (int i = 1; i < rows; i++) {
            Row row = sheet.getRow(i);
            ScStudent scStudent = new ScStudent();
            //姓名
            scStudent.setStuname(row.getCell(0).toString());
            //编码
            scStudent.setStucode(row.getCell(1).toString());
            //状态
            scStudent.setState((long) ((int) row.getCell(3).getNumericCellValue()));
            //手机号码
            Cell cell = row.getCell(4);

            scStudent.setStuphone(cell.toString());
            //家庭住址
            scStudent.setStuaddress(row.getCell(5).toString());
            //毕业学校
            scStudent.setStugraduatefrom(row.getCell(6).toString());
            //年龄
            scStudent.setStuage((long) ((int) row.getCell(7).getNumericCellValue()));
            //升高
            scStudent.setStuheight((long) ((int) row.getCell(8).getNumericCellValue()));
            //体重
            scStudent.setStuweight((long) ((int) row.getCell(9).getNumericCellValue()));
            //性别
            scStudent.setStusex(row.getCell(10).toString());
            //密码
            scStudent.setPassword((int) row.getCell(11).getNumericCellValue());
            // 添加学生
            scStudentMapper.insertScStudent(scStudent);
            //班级编号（如果为null代表是在学生表中导入的不给学员班级编号）
            if (clazzId != null) {
                // 根据班级编号找到该班级
                ScClazz scClazz = scClazzMapper.selectScClazzById(clazzId);
                Integer studentCode = Integer.valueOf(sysConfigService.selectConfigByKey("student_code"));

                ScStudentClazz scStudentClazz = new ScStudentClazz(clazzId, scStudent.getId(), scClazz.getGradeid(), studentCode, DateUtils.getLocalDateTime());
                // 添加学员班级
                scStudentClazzMapper.insertScStudentClazz(scStudentClazz);

                // 修改学生班级编号
                scStudent.setStudentclazzid(scStudentClazz.getId());
                scStudentMapper.updateScStudent(scStudent);

                // 添加学员课程
                ScClazzSubject scClazzSubject = new ScClazzSubject();
                scClazzSubject.setClazzid(clazzId);
                List<ScClazzSubject> scClazzSubjectList = scClazzSubjectMapper.selectScClazzSubjectList(scClazzSubject);
                scClazzSubjectList.forEach(item -> {
                    // 找到课程
                    ScSubject scSubject = scSubjectMapper.selectScSubjectBySubid(item.getSubid());
                    ScStudentSubject scStudentSubject = new ScStudentSubject(item.getSubid(), scStudent.getId(), scSubject.getSubtime(), 0L);
                    scStudentSubjectMapper.insertScStudentSubject(scStudentSubject);
                });

            }
        }
    }

    /**
     * 查询可参加此次考试的学生
     * @param scStudent
     * @return
     */
    @Override
    public List<ScStudent> listCanJoinExamStudent(ScStudent scStudent) {
        return scStudentMapper.listCanJoinExamStudent(scStudent);
    }

    /**
     * 查询绑定本次考试的学生
     * @param scStudent
     * @return
     */
    @Override
    public List<ScStudent> listBindExam(ScStudent scStudent) {
        return scStudentMapper.listBindExam(scStudent);
    }

    /**
     *
     * 查询绑定了寝室的学生
     * @param scStudent
     * @return
     */
    @Override
    public List<ScStudent> listCanJoinSleepRoom(ScStudent scStudent) {

        List<Long> sleep_room_person_type_stu = JSON.parseArray(sysConfigService.selectConfigByKey("sleep_room_person_type_stu"), Long.class);
        //所有学生
        List<ScStudent> scStudents = scStudentMapper.listCanJoinSleepRoom(scStudent, sleep_room_person_type_stu);

        return scStudents;
    }

    /**
     *
     * 查询未绑定了寝室的学生
     * @param scStudent
     * @return
     */
    @Override
    public List<ScStudent> listCanNotJoinSleepRoom(ScStudent scStudent) {
     //   List<Long> sleep_room_person_type_stu = JSON.parseArray(sysConfigService.selectConfigByKey("sleep_room_person_type_stu"), Long.class);
        return scStudentMapper.listCanNotJoinSleepRoom(scStudent);
    }


}
